package cloud.maque.auth.common;

import cloud.maque.auth.conf.AuthProperties;
import cloud.maque.auth.handler.login.LoginHandlerInterface;
import cloud.maque.auth.handler.oauth2callback.Oauth2CallBackInterface;
import cloud.maque.auth.model.LoginRequest;
import cloud.maque.auth.model.LoginResponse;
import cloud.maque.auth.model.Oauth2AccessTokenRes;
import cloud.maque.auth.model.Oauth2User;
import cloud.maque.common.core.enums.LoginType;
import cloud.maque.common.core.response.R;
import cloud.maque.sso.client.service.Oauth2Service;
import cloud.maque.sso.client.utils.SoMap;
import cn.dev33.satoken.temp.SaTempUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.util.IdUtil;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;

/**
 * 通用的Oauth2回调，如果不一样，各个模块自行实现
 */
@Component
public class CommnCallBack {


    @Autowired
    Oauth2CallBackInterface backInterface;

    @Autowired
    LoginHandlerInterface loginHandlerInterface;


    @Autowired
    AuthProperties authProperties;


    @Autowired
    HttpSession httpSession;

    @Autowired
    Oauth2Service oauth2Service;


    public R<LoginResponse> CallBack(String code, String ajax, LoginType loginType) throws IOException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse httpServletResponse = attributes.getResponse();

        Oauth2AccessTokenRes token = backInterface.getAccessToken(code, loginType.name());
        //再根据Token去获取用户信息
        Oauth2User user = backInterface.getUser(token.getAccessToken(), loginType.name());
        //登录
        LoginRequest<Oauth2User> request = new LoginRequest<>();
        request.setData(user);
        request.setLoginType(loginType);
        LoginResponse response = loginHandlerInterface.login(request);

        //跳到绑定界面,会携带一个临时的Token
        if (response.getIsRedirectBind()) {
            String tmpToken = SaTempUtil.createToken(IdUtil.fastSimpleUUID(), 10000);
            String url = SaFoxUtil.joinParam(authProperties.getBindUserUrl(), "token", tmpToken);
            if (!"1".equalsIgnoreCase(ajax)) {
                httpSession.setAttribute("loginType", request.getLoginType());
                httpSession.setAttribute("data", user);
            }
            httpServletResponse.sendRedirect(url);
            return null;
        }

        //调用SSO-Server获取Token
        SaResult saResult = oauth2Service.ThrirdGetAccessToken(loginType, user.getUserId());
        if (saResult.getCode() != 200) {
            return R.error(saResult.getMsg());
        }

        response.setAccessToken(saResult.get("data", SoMap.class).get("access_token").toString());
        response.setRefreshToken(saResult.get("data", SoMap.class).get("refresh_token").toString());

        //Ajax直接输出数据
        if ("1".equalsIgnoreCase(ajax)) {
            return R.ok("验证成功", response);
        } else {
            //非Ajax跳转页面,由于这种类型只在演示时出现，所以地址直接写死
            httpSession.setAttribute("userId", response.getUserId());
            httpSession.setAttribute("userName", response.getUserName());
            httpSession.setAttribute("accessToken", response.getAccessToken());
            httpServletResponse.sendRedirect("/");
            return null;
        }
    }
}
